#include "apue.h"
#include <time.h>

void sig_alarm(int signo) {
}

void settimeout(void (* callback)(void), int intval) {
    if (intval <= 0) {
        callback();
        return;
    }
    struct sigaction alarmaction, oldaction;
    alarmaction.sa_handler= sig_alarm;
    alarmaction.sa_flags= 0;
    sigemptyset(&alarmaction.sa_mask);
    if (sigaction(SIGALRM, &alarmaction, &oldaction) < 0)
        err_sys("sigaction error");

    sigset_t noblockset, alarmset, oldset;     
    sigemptyset(&alarmset);
    sigemptyset(&noblockset);
    sigaddset(&alarmset, SIGALRM);

    if (sigprocmask(SIG_BLOCK, &alarmset, &oldset) < 0)
        err_sys("SIG_BLOCK error");
    alarm(intval);
    sigsuspend(&noblockset);

    sigprocmask(SIG_SETMASK, &oldset, NULL);
    sigaction(SIGALRM, &oldaction, NULL);

    callback();
}

static int timeval;

void test_settimeout(void) {
    char buf[20];
    time_t timestamp= time(NULL);
    struct tm * nowtm= localtime(&timestamp);
    strftime(buf, 20, "%Y-%m-%d %H:%M:%S", nowtm);
    printf("now: %s\n", buf);

    if (timeval > 10) {
        return;
    }
    printf("sleep %d second.\n", ++timeval);
    settimeout(test_settimeout, timeval);
}

int main(void) {
    settimeout(test_settimeout, 0);
}


